package lei;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

public class Main1 {

    /**
     * 反射
     * 1. 获取Class对象
     * 2. 获取类的属性
     * 3. 获取类的方法
     * 4. 获取类构造方法
     * 5. 获取类中的成员变量
     * @param args
     * @throws ClassNotFoundException
     * @throws Exception
     */
    public static void main(String[] args) throws ClassNotFoundException, Exception {
        System.out.println("Hello world!");


       Class<?> clazz = Class.forName("lei.TeacherDto");

        System.out.println(clazz.getName());

        System.out.println(TeacherDto.class.getName());


        Constructor<?> constructor = clazz.getConstructor();

        TeacherDto obj = (TeacherDto)constructor.newInstance();







        // 获取字段并设置值
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);  // 突破私有访问限制
        nameField.set(obj, "张三");

        Field ageField = clazz.getDeclaredField("age");
        ageField.setAccessible(true);
        ageField.setInt(obj, 20);  // 直接设置最终值

        Field professionField = clazz.getDeclaredField("Job");
        professionField.setAccessible(true);
        professionField.set(obj, "老师");

        obj.setJob("医生");

        String Job= (String) professionField.get(obj);
        System.out.println( Job);

        System.out.println(obj.getJob());

        //在您提供的代码中，主要有两种设置对象属性的方式，它们有显著区别：

        /**
         特性	    反射设置字段	                Setter方法调用
         访问级别	突破封装性（即使private字段）	遵守封装原则（需public方法）
         执行路径	直接修改内存中的字段值	        通过方法调用修改字段
         验证逻辑	绕过Setter中的验证逻辑	        执行Setter中的业务逻辑
         性能	    较高（直接内存操作）	        较低（方法调用开销）
         代码可读性	较低（反射代码较复杂）	        较高（标准面向对象）
         类型安全	运行时检查                   	编译时检查
         字段名要求	需精确匹配字段名（区分大小写）	只需方法名匹配
         */

        System.out.println( obj);


       Object cal=  clazz.getConstructor().newInstance();//获取共有的构造方法
       Method method1=clazz.getMethod("add", int.class, int.class);

      int sum=(int) method1.invoke(cal,1,2);
      System.out.println(sum);


     Method method2=clazz.getDeclaredMethod("multiply", int.class, int.class);
     method2.setAccessible(true);

     int m=(int) method2.invoke(cal,1,2);
     System.out.println(m);


     // 获取 TeacherDto 类中所有声明的字段（包括私有字段）
     Field[] fields = clazz.getDeclaredFields();
     
     // 打印每个字段的详细信息
     for (Field field : fields) {
         System.out.println("字段名称：" + field.getName() + 
                            "，类型：" + field.getType().getSimpleName() + 
                            "，访问权限：" + java.lang.reflect.Modifier.toString(field.getModifiers()));
     }

     //获取
     // 获取 TeacherDto 类中所有声明的方法（包括私有方法）
     Method[] methods = clazz.getDeclaredMethods();
     
     // 打印每个方法的详细信息
     for (Method method : methods) {
         System.out.println("方法名称：" + method.getName() + 
                            "，返回类型：" + method.getReturnType().getSimpleName() + 
                            "，访问权限：" + java.lang.reflect.Modifier.toString(method.getModifiers()));
     }

    }
}

 class TeacherDto {
    private String name;
    private int age;

    private String Job;

    public TeacherDto() {
    }

    public TeacherDto(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return Job;
    }

    public void setJob(String job) {
        Job = job;
    }


    public int add(int a, int b) {
        return a + b;
    }

    private int multiply(int a, int b) {
        return a * b;
    }

    @Override
    public String toString() {
        return "TeacherDto{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", Job='" + Job + '\'' +
                '}';
    }
}
